package lbim.client.ui;

import java.io.IOException;
import java.util.Hashtable;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.Displayable;

import de.enough.polish.ui.Alert;
import de.enough.polish.ui.List;
import de.enough.polish.util.Locale;
import javax.microedition.location.LocationException;
import lbim.client.main.LoginListener;
import lbim.client.main.LogoutListener;
import lbim.client.main.PresenceListener;
import lbim.client.model.Account;
import lbim.client.model.Response;
import lbim.protocol.Controller;

/**
 *
 * @author tharindu
 */
public class MainUI implements LoginListener, LogoutListener, PresenceListener{

    //Screen codes: unused regard to memory
    final public static int SCR_SPLASH = 0;
    final public static int SCR_PROGRESS = 1;
    final public static int SCR_MAIN = 2;
    final public static int SCR_LOGIN = 3;
    final public static int SCR_TABBED = 4;
    final public static int SCR_ABOUT = 5;
    final public static int SCR_HELP = 6;
    final public static int SCR_SETTINGS = 7;
    final public static int SCR_MAP = 8;

    
    //Commands codes:
    final public static int CMD_OK = 1;
    final public static int CMD_CANCEL = 2;
    final public static int CMD_YES = 3;
    final public static int CMD_NO = 4;
    final public static int CMD_BACK = 5;
    final public static int CMD_EXIT = 6;
    final public static int CMD_HOME = 7;
    final public static int CMD_LOGOUT = 8;
    final public static int CMD_SAVE = 9;
    final public static int CMD_MAP = 10;

    //Commands:
    final private static Command cmdOk = new Command(Locale.get("command.ok"), Command.OK, 5);//[LOCALE]
    final private static Command cmdCancel = new Command(Locale.get("command.cancel"), Command.CANCEL, 1);//[LOCALE]
    final private static Command cmdYes = new Command(Locale.get("command.yes"), Command.OK, 1);//[LOCALE]
    final private static Command cmdNo = new Command(Locale.get("command.no"), Command.CANCEL, 2);//[LOCALE]
    final private static Command cmdBack = new Command(Locale.get("command.back"), Command.BACK, 1);//[LOCALE]
    final private static Command cmdExit = new Command(Locale.get("command.exit"), Command.CANCEL, 1);//[LOCALE]
    final private static Command cmdHome = new Command(Locale.get("command.home"), Command.CANCEL, 1);//[LOCALE]
    final private static Command cmdLogout = new Command(Locale.get("command.logout"), Command.OK, 3);//[LOCALE]
    final private static Command cmdSave = new Command(Locale.get("command.save"), Command.OK, 1);//[LOCALE]
    final private static Command cmdMap = new Command(Locale.get("command.map"), Command.OK, 2);//[LOCALE]

    //commands list
    static private Hashtable commands_ = new Hashtable();

    //	 Associate commands and commands codes
    static {
        commands_.put(new Integer(CMD_OK), cmdOk);
        commands_.put(new Integer(CMD_CANCEL), cmdCancel);
        commands_.put(new Integer(CMD_YES), cmdYes);
        commands_.put(new Integer(CMD_NO), cmdNo);
        commands_.put(new Integer(CMD_BACK), cmdBack);
        commands_.put(new Integer(CMD_EXIT), cmdExit);
        commands_.put(new Integer(CMD_HOME), cmdHome);
        commands_.put(new Integer(CMD_LOGOUT), cmdLogout);
        commands_.put(new Integer(CMD_SAVE), cmdSave);
        commands_.put(new Integer(CMD_MAP), cmdMap);
    }

    // screens:
    private static MainScreen scrMain;
    private static LoginScreen scrLogin;
    private static TabbedScreen scrTabbed;
    private static Splash scrSplash;
    private static About scrAbout;
    private static Help scrHelp;
    private static Settings scrSettings;
    private static ProgressScreen scrProgress;
    private static MapCanvas scrMap;

    private static MainUI ui_; //MainUI object
    private static MainMidlet mainMidlet_; //MainMidlet object

    private static Account account_;
    
    public static Controller controller_;

    public MainUI() {
        ui_ = this;
        mainMidlet_ = MainMidlet.getInstance();

        // Init screens:
        scrMain = new MainScreen();
        scrLogin = new LoginScreen();
        scrSplash = new Splash();
        scrAbout = new About();
                
        scrHelp = new Help();
        scrSettings = new Settings();
        scrProgress = new ProgressScreen();
        
        try {
            scrTabbed = new TabbedScreen();
        } catch (IOException ex) {
            System.out.println("[MainUI] tabbed screen init error: " + ex.getMessage());
        }
        try {
            controller_ = new Controller();
            scrMap = new MapCanvas(controller_);
        } catch (LocationException lex) {
            // if JSR-179 is not available, controller will use cellid, if JSR -179 available and if there is a problem..
            System.out.println("[MainUI] location not available cant continue");
        }
    }

    public static MainUI getInstance() {
        return ui_;
    }

    public Hashtable getCommands() {
        return commands_;
    }

    public static void hsenidCommand(Command c, Displayable d) {
        if (d == scrMain) {  // [SCR_MAIN] - COMMANDS
            if (c == List.SELECT_COMMAND) {
                int selected = scrMain.getSelectedIndex();
                switch (selected) {
                    case 0:
                        ui_.setView(SCR_SETTINGS); // [SCREEN]
                        break;
                    case 1:
                        ui_.setView(SCR_LOGIN); // [SCREEN]
                        break;
                    case 2:
                        ui_.setView(SCR_HELP); // [SCREEN]
                        break;
                    case 3:
                        ui_.setView(SCR_ABOUT); // [SCREEN]
                        break;
                }
            } else if (c == cmdExit) {
                if(account_.isConnected()) {
                    controller_.disconnect();
                }
                mainMidlet_.notifyDestroyed();
            }
        } else if (d == scrLogin) {
            if (c == cmdBack) {
                ui_.setView(SCR_MAIN); // [SCREEN]
            } else if(c == cmdOk) {
                ui_.setView(SCR_PROGRESS); // [SCREEN]
                //account_ = new Account(scrLogin.getUsername(), scrLogin.getPassword(), scrSettings.getServerUrl());
                account_ = new Account(scrLogin.getUsername(), "123", scrSettings.getServerUrl());
                System.out.println("[MainUI] username: " + scrLogin.getUsername() + " password: " + scrLogin.getPassword());
                // Setting All Listeners
                account_.setLoginListener(ui_);
                account_.setLogoutListener(ui_);
                account_.setChatListener(scrTabbed);
                account_.setPresenceListener(ui_);
                account_.setMapUpdateListener(scrMap);
                controller_.setAccount(account_);

                int x = scrMap.getWidth() + 100;
                int y = scrMap.getHeight() + 100;
                String mapResolution = "" + x + "x" + y;
                controller_.setMapResolution(mapResolution);

                controller_.connect();
            }
        } else if (d == scrTabbed) {
            if (c == cmdMap) {
                ui_.setView(SCR_MAP); // [SCREEN]
            } else if (c == cmdLogout) {
                ui_.setView(SCR_PROGRESS); // [SCREEN]
                controller_.disconnect();
            }
        } else if (d == scrHelp) {
            ui_.setView(SCR_MAIN); // [SCREEN]
        } else if (d == scrAbout) {
            ui_.setView(SCR_MAIN); // [SCREEN]
        } else if (d == scrSettings) {
            if (c == cmdSave) {
                //TODO: Save Server Url
                ui_.setView(SCR_MAIN); // [SCREEN]
            } else if (c == cmdCancel) {
                ui_.setView(SCR_MAIN); // [SCREEN]
            }
        }
    }

    public void setView(int display) {
        switch (display) {
            case SCR_SPLASH:
                mainMidlet_.setDisplay(scrSplash);
                break;
            case SCR_LOGIN:
                mainMidlet_.setDisplay(scrLogin);
                break;
            case SCR_PROGRESS:
                mainMidlet_.setDisplay(scrProgress);
                break;
            case SCR_MAIN:
                mainMidlet_.setDisplay(scrMain);
                break;
            case SCR_TABBED:
                mainMidlet_.setDisplay(scrTabbed);
                break;
            case SCR_ABOUT:
                mainMidlet_.setDisplay(scrAbout);
                break;
            case SCR_HELP:
                mainMidlet_.setDisplay(scrHelp);
                break;
            case SCR_SETTINGS:
                mainMidlet_.setDisplay(scrSettings);
                break;
            case SCR_MAP:
                controller_.sendLocationUpdate();
                scrMap.init();
                mainMidlet_.setDisplay(scrMap);
                break;
        }
    }

    public void setAlert(String text, javax.microedition.lcdui.Displayable displayable) {
        //#style confirmationAlert
        Alert alert = new Alert(null);

        //#style alertGradient
        alert.setString(text);

        Alert.setCurrent(mainMidlet_.getDisplay(), alert, displayable);
        mainMidlet_.setDisplay(alert);

    }

    public void sendMessage(String contact, String message) {
        Thread t = new MessageThread(contact, message);
        t.start();
    }

    public void loginResponseReceived(int code) {
        System.out.println("[MainUI] loginResponseReceived() code:" + code );
        switch(code) {
            case Response.OK:
                account_.setConnected(true);
                controller_.sendPresenceReqMessage();
                break;
            default:
                account_.setConnected(false);
                break;
        }
    }

    public void presenceResponseReceived(String presenceList) {
        System.out.println("[MainUI] presenceResponseReceived: " + presenceList);
        try {
            scrTabbed.resetUi(presenceList);
        } catch (IOException ex) {
            ui_.setAlert("Failed to setup chat screen", scrTabbed);
        }
        ui_.setView(SCR_TABBED); // [SCREEN]
    }

    public void logoutResponseReceived(int code, String description) {
        System.out.println("[MainUI] logoutResponseReceived() code: " + code + " description: " + description);
        try {
            Thread.sleep(500);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
        if(code != Response.OK) {
            ui_.setAlert("Logout has been interupted or not successful", scrMain);
        }
        ui_.setView(SCR_MAIN); // [SCREEN]
    }
    
    private class MessageThread extends Thread {

        private String receiver;
        private String message;

        MessageThread(String receiver, String message) {
            this.receiver = receiver;
            this.message = message;
        }

        public void run() {
            MainUI.controller_.sendChatMessage(message, receiver);
        }
    }

}


